package be.myandroid.games.menu;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import be.myandroid.games.Configuration;
import be.myandroid.games.R;
import be.myandroid.games.menu.AbstractMenu.callBack;
import be.myandroid.games.spritetext.LabelMaker;
import be.myandroid.games.spritetext.NumericSprite;
import be.myandroid.games.spritetext.Projector;

public class MenuMaker implements callBack{
	private String TAG ="GameMenu";
	
	private static MenuMaker instance;
	
    private int mWidth;
    private int mHeight;
    private int mFrames;
    private int mMsPerFrame;
    private final static int SAMPLE_PERIOD_FRAMES = 12;
    private final static float SAMPLE_FACTOR = 1.0f / SAMPLE_PERIOD_FRAMES;
    private long mStartTime = 0;
    private LabelMaker mLabels;
    private Paint mLabelPaint;
    private int mLabelMsPF;
    private Projector mProjector;
    private NumericSprite mNumericSprite;
    private Drawable background;
    private static int STRIKE_HEIGHT = 512;
    private static int STRIKE_WIDTH = 1024;
    private AbstractMenu menu;
    
	private MenuMaker(final Context context){
        mProjector = new Projector();
        mLabelPaint = new Paint();
        mLabelPaint.setTextSize(32);
        mLabelPaint.setAntiAlias(true);
        mLabelPaint.setARGB(0xff, 0xFF, 0xFF, 0xFF);
        background = context.getResources().getDrawable(R.drawable.menu_background);
	}
	
	public void notifyChange(){
		menu.layoutItems(mWidth, mHeight);
	}
	
	public static MenuMaker getInstance(GL10 gl, Context context, AbstractMenu menu){
		if(instance == null)
			instance = new MenuMaker(context);
		
		instance.menu = menu;
		menu.parent = instance;
		instance.initshapes(gl);
		//instance.notifyChange();
		return instance;
	}
	
	public void initshapes(GL10 gl){
        // Enable use of vertex arrays
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        if (mLabels != null) {
            mLabels.shutdown(gl);
        } else {
            mLabels = new LabelMaker(true, STRIKE_WIDTH, STRIKE_HEIGHT);
        }
        mLabels.initialize(gl);
        mLabels.beginAdding(gl);
        
        menu.initialize(gl, background, mLabels, mLabelPaint);
        
        mLabelMsPF = mLabels.add(gl, "FPS", mLabelPaint);
        
        mLabels.endAdding(gl);

        if (mNumericSprite != null) {
            mNumericSprite.shutdown(gl);
        } else {
            mNumericSprite = new NumericSprite();
        }
        mNumericSprite.initialize(gl, mLabelPaint);
	}

	public void draw(GL10 gl){
        mProjector.getCurrentModelView(gl);
        mLabels.beginDrawing(gl, mWidth, mHeight);
        menu.draw(gl,mLabels,mProjector);
        //item.draw(gl, mLabels, mProjector);
        
        if(Configuration.getInstance().showFPS) {
        	float msPFX = mWidth - mLabels.getWidth(mLabelMsPF) - 1;
        	mLabels.draw(gl, msPFX, 0, mLabelMsPF);
        	mLabels.endDrawing(gl);
        	//drawMsPF(gl, msPFX);
        	drawFramePSec(gl, msPFX);
        } else
        	mLabels.endDrawing(gl);        	
	}
	
	private void drawFramePSec(GL10 gl, float rightMargin) {
        long time = SystemClock.uptimeMillis();
        if (mStartTime == 0) {
            mStartTime = time + 1000;
        }
        mFrames++;
        if (mStartTime < time) {
        	mStartTime = time + 1000;
            mNumericSprite.setValue(mFrames);            
            mFrames = 0;
        }
        float numWidth = mNumericSprite.width();
        float x = rightMargin - numWidth;
        mNumericSprite.draw(gl, x, 0, mWidth, mHeight);
    }
    
    private void drawMsPF(GL10 gl, float rightMargin) {
        long time = SystemClock.uptimeMillis();
        if (mStartTime == 0) {
            mStartTime = time;
        }
        if (mFrames++ == SAMPLE_PERIOD_FRAMES) {
            mFrames = 0;
            long delta = time - mStartTime;
            mStartTime = time;
            mMsPerFrame = (int) (delta * SAMPLE_FACTOR);
        }
        if (mMsPerFrame > 0) {
            mNumericSprite.setValue(mMsPerFrame);
            float numWidth = mNumericSprite.width();
            float x = rightMargin - numWidth;
            mNumericSprite.draw(gl, x, 0, mWidth, mHeight);
        }
    }
    
    public void OnSurfaceChanged(GL10 gl, int width, int height){
        mWidth = width;
        mHeight = height;
        mProjector.setCurrentView(0, 0, width, height);
        menu.layoutItems(mWidth, mHeight);
    }
    
    public void getCurrentProjection(GL10 gl){
    	mProjector.getCurrentProjection(gl);
    }
}
